/**
 * 
 */
package com.nari.baseinfo.service;

import java.io.File;
import java.math.BigDecimal;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;

import com.nari.baseinfo.dao.IBuildingDao;
import com.nari.baseinfo.dao.IBuildingUnitDao;
import com.nari.baseinfo.dao.ICommunityDao;
import com.nari.baseinfo.dao.IConcentratorDao;
import com.nari.baseinfo.dao.IHeatRoomDao;
import com.nari.baseinfo.dao.IProjectDao;
import com.nari.baseinfo.model.IBuilding;
import com.nari.baseinfo.model.IBuildingUnit;
import com.nari.baseinfo.model.IConcentrator;
import com.nari.baseinfo.model.IHeatRoom;
import com.nari.baseinfo.utils.excelupload.BaseInfoExcelParser;
import com.nari.baseinfo.utils.excelupload.parseentity.ExcelAssignMeterEntity;
import com.nari.baseinfo.utils.excelupload.parseentity.ExcelHeatSinkerEntity;
import com.nari.baseinfo.utils.excelupload.parseentity.ExcelRecordEntity;
import com.nari.basic.dao.IRoleDao;
import com.nari.basic.dao.IUserDao;
import com.nari.basic.dao.IUserRoleDao;
import com.nari.basic.model.IRole;
import com.nari.basic.model.IUser;
import com.nari.basic.model.IUserRole;
import com.nari.heatshare.dao.IAssignMeterDao;
import com.nari.heatshare.model.IAssignMeter;
import com.nari.platform.model.ResponseMsg;
import com.nari.sink.bo.PSinkInfo;
import com.nari.sink.dao.ISinkDao;

/**
 * 
 * @author Xiaopeng
 * @date 2013-12-23
 */
public class BaseInfoExcelUploadServiceImpl implements IBaseInfoExcelUploadService {
	private IProjectDao iProjectDao;
	private ICommunityDao iCommunityDao;
	private IBuildingDao iBuildingDao;
	private IBuildingUnitDao iBuildingUnitDao;
	private IHeatRoomDao iHeatRoomDao;
	private IConcentratorDao iConcentratorDao;
	private IAssignMeterDao iAssignMeterDao;
	private ISinkDao iSinkDao;
	private IUserDao iUserDao;
	private IRoleDao iRoleDao;
	private IUserRoleDao iUserRoleDao;
	private String sysCommonUserRole;
	
	/**
	 * 系统基础信息资料上传
	 * @param excelFile 基础资料Excel文件
	 * @param excelFileName 
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-1-11
	 */
	public ResponseMsg saveOrUpdateBaseInfo(File excelFile, String excelFileName) throws Exception {
		//Excel文件解析
		BaseInfoExcelParser excelParser = BaseInfoExcelParser.getInstance();
		ResponseMsg rmsg = excelParser.parseBaseInfoExcel(excelFile, excelFileName);
		if(rmsg.isSuccess()) {
			Map<Integer, ExcelRecordEntity> baseDataMap = excelParser.getExcelParseData();
			for(Iterator<Integer> it=baseDataMap.keySet().iterator(); it.hasNext();) {
				//用户基础信息实体
				ExcelRecordEntity recordEntity = baseDataMap.get(it.next());
				//热用户信息入库
				rmsg = this.saveOrUpdateHeatRoomInfo(recordEntity);
				if(!rmsg.isSuccess()) {
					return rmsg;
				}
				//系统用户信息入库
				rmsg = this.saveOrUpdateHeatUserInfo(recordEntity);
				if(!rmsg.isSuccess()) {
					return rmsg;
				}
				//散热器信息入库
				rmsg = this.saveOrUpdateHeatSinkerInfo(recordEntity);
				if(!rmsg.isSuccess()) {
					return rmsg;
				}
				//分配表、集中器信息入库
				rmsg = this.saveOrUpdateAssignMeterAndConcentratorInfo(recordEntity);
				if(!rmsg.isSuccess()) {
					return rmsg;
				}
			}
		}
		return rmsg;
	}
	
	/**
	 * 热用户信息入库
	 * @param recordEntity
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-1-12
	 */
	public ResponseMsg saveOrUpdateHeatRoomInfo(ExcelRecordEntity recordEntity) throws Exception {
		//查询热用户对应的楼栋信息
		IBuilding building = iBuildingDao.queryBuildingInfoByBuildingID(recordEntity.getBuildingID());
		if(building == null) {
			String msg = "缺少建筑物编号为【"
					+recordEntity.getBuildingID()
					+"】的楼栋信息！";
			return ResponseMsg.getInstance(false, msg);
		}
		//查询热用户对应的单元信息
		IBuildingUnit unit = iBuildingUnitDao.queryUnitInfoByUnitName(recordEntity.getUnitName(), recordEntity.getBuildingID());
		if(unit == null) {
			unit = new IBuildingUnit();
			unit.setUnitName(recordEntity.getUnitName());
			unit.setBuildingID(building.getId());
			this.iBuildingUnitDao.saveEntity(unit);
		}
		//构造热用户信息
		IHeatRoom heatRoom = iHeatRoomDao.queryRoomInfoByhouseNoBuildingUID(recordEntity.getHouseNo(), building.getId());
		if(heatRoom == null) {
			heatRoom = new IHeatRoom();
		}
		//房间号
		heatRoom.setHouseNo(recordEntity.getHouseNo());
		//所属项目
		heatRoom.setProjectID(building.getProjectID());
		//所属小区
		heatRoom.setCommunityID(building.getCommunityID());
		//所属楼栋
		heatRoom.setBuildingID(building.getId());
		//所属单元
		heatRoom.setUnitID(unit.getId());
		//楼层
		heatRoom.setFloorIndex(recordEntity.getFloorIndex());
		//楼层位置
		heatRoom.setFloorPosition(recordEntity.getFloorPosition());
		//是否为边户
		heatRoom.setIfSideRoom(recordEntity.getIfSideRoom());
		//户主姓名
		heatRoom.setRoomOwner(recordEntity.getUserName());
		//联系方式
		heatRoom.setOwnerTel(recordEntity.getPhone());
		//建筑面积
		heatRoom.setStructArea(recordEntity.getStructArea());
		//供热面积
		heatRoom.setHeatArea(recordEntity.getHeatArea());
		//是否参与分摊
		heatRoom.setIfMeasureCharge(recordEntity.getIfMeasureCharge());
		//户修正系数
		heatRoom.setReviseFactor(recordEntity.getReviseFactor());
		this.iHeatRoomDao.saveOrUpdateEntity(heatRoom);
		return ResponseMsg.getInstance(true, "");
	}
	
	/**
	 * 热用户个人信息入库
	 * @param recordEntity
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-1-12
	 */
	public ResponseMsg saveOrUpdateHeatUserInfo(ExcelRecordEntity recordEntity) throws Exception {
		//楼栋信息
		IBuilding building = iBuildingDao.queryBuildingInfoByBuildingID(recordEntity.getBuildingID());
		//热用户信息
		IHeatRoom heatRoom = iHeatRoomDao.queryRoomInfoByhouseNoBuildingUID(recordEntity.getHouseNo(), building.getId());
		//热用户登录名 = 楼栋号 + 门牌号 + 用户姓名
		String userID = recordEntity.getBuildingID() + recordEntity.getHouseNo() + recordEntity.getUserName();
		//构造热用户信息
		IUser user = iUserDao.saveOrUpdateUser(userID);
		//用户姓名
		user.setUserName(recordEntity.getUserName());
		//联系电话
		user.setPhone(recordEntity.getPhone());
		//状态：有效
		user.setStatus("1");
		//系统用户关联热用户
		user.setRoomId(heatRoom.getId());
		iUserDao.saveOrUpdateEntity(user);
		//设置热用户角色
		IRole role = iRoleDao.queryRoleInfoByRoleID(sysCommonUserRole);
		if(role == null) {
			return ResponseMsg.getInstance(false, "热用户角色不存在，请联系管理员添加角色编号为【"+sysCommonUserRole+"】的角色信息！");
		}
		int userRoleRelCounter = iUserRoleDao.countByUserUIDAndRoleUID(user.getId(), role.getId());
		if(userRoleRelCounter == 0) {
			IUserRole userRole = new IUserRole();
			userRole.setUserUuid(user.getId());
			userRole.setRoleUuid(role.getId());
			this.iUserRoleDao.saveEntity(userRole);
		}
		return ResponseMsg.getInstance(true, "");
	}
	
	/**
	 * 散热器信息入库
	 * @param recordEntity
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-1-12
	 */
	public ResponseMsg saveOrUpdateHeatSinkerInfo(ExcelRecordEntity recordEntity) throws Exception {
		if(recordEntity.getHeatSinkerList().size()>0) {
			//楼栋信息
			IBuilding building = iBuildingDao.queryBuildingInfoByBuildingID(recordEntity.getBuildingID());
			//热用户信息
			IHeatRoom heatRoom = iHeatRoomDao.queryRoomInfoByhouseNoBuildingUID(recordEntity.getHouseNo(), building.getId());
			for(ExcelHeatSinkerEntity sinkerEntity: recordEntity.getHeatSinkerList()) {
				//散热器编号与分配表表号默认一致，表号重复，则分配表、散热器无法导入
				int counter = iAssignMeterDao.countMeterNumBySeriousNum(sinkerEntity.getSinkNo(), heatRoom.getId());
				if(counter > 0) {
					return ResponseMsg.getInstance(false, "系统中存在重复的分配表表号【"+sinkerEntity.getSinkNo()+"】，分配表信息保存失败！");
				}
				//构造散热器信息
				PSinkInfo sinker = iSinkDao.querySinkerBySinkNo(sinkerEntity.getSinkNo(), heatRoom.getId());
				if(sinker == null) {
					sinker = new PSinkInfo();
				}
				BeanUtils.copyProperties(sinker, sinkerEntity);
				//散热器功率修正系数Kq = 散热器单片功率 × 散热器片数
				double kqFactor = new BigDecimal(sinker.getCalPower())
						.multiply(new BigDecimal(sinker.getPieceNum()))
						.doubleValue();
				sinker.setKqFactor(kqFactor);
				//所属项目
				sinker.setProjectID(heatRoom.getProjectID());
				//所属小区
				sinker.setCommunityID(heatRoom.getCommunityID());
				//所属楼栋
				sinker.setBuildingID(heatRoom.getBuildingID());
				//所属热用户
				sinker.setRoomId(heatRoom.getId());
				this.iSinkDao.saveOrUpdateEntity(sinker);
			}
		}
		return ResponseMsg.getInstance(true, "");
	}
	
	/**
	 * 分配表和集中器信息入库
	 * @param recordEntity
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-1-12
	 */
	public ResponseMsg saveOrUpdateAssignMeterAndConcentratorInfo(ExcelRecordEntity recordEntity) 
			throws Exception {
		if(recordEntity.getAssignMeterList().size() > 0) {
			//楼栋信息
			IBuilding building = iBuildingDao.queryBuildingInfoByBuildingID(recordEntity.getBuildingID());
			//热用户信息
			IHeatRoom heatRoom = iHeatRoomDao.queryRoomInfoByhouseNoBuildingUID(recordEntity.getHouseNo(), building.getId());
			for(ExcelAssignMeterEntity meterEntity: recordEntity.getAssignMeterList()) {
				String seriousNum = meterEntity.getSeriousNum();
				//散热器编号与分配表表号默认一致，表号重复，则分配表、散热器无法导入
				int counter = iAssignMeterDao.countMeterNumBySeriousNum(seriousNum, heatRoom.getId());
				if(counter > 0) {
					return ResponseMsg.getInstance(false, "系统中存在重复的分配表表号【"+seriousNum+"】，分配表信息保存失败！");
				}
				//集中器号
				String concentratorNo = seriousNum.substring(0, seriousNum.length()-3);
				//集中器信息入库
				IConcentrator concentrator = iConcentratorDao.queryByConcentratorNo(concentratorNo);
				if(concentrator == null) {
					concentrator = new IConcentrator();
				}
				//所属项目
				concentrator.setProjectID(building.getProjectID());
				//所属小区
				concentrator.setCommunityID(building.getCommunityID());
				//所属楼栋
				concentrator.setBuildingID(building.getId());
				//集中器号
				concentrator.setConcentratorNo(concentratorNo);
				iConcentratorDao.saveOrUpdateEntity(concentrator);
				//分配表信息入库
				IAssignMeter assignMeter = iAssignMeterDao.queryMeterInfoBySeriousNum(seriousNum, heatRoom.getId());
				if(assignMeter == null) {
					assignMeter = new IAssignMeter();
				}
				//分配表表号
				assignMeter.setSeriousNum(seriousNum);
				//散热器ID，散热器编号与分配表编号一一对应
				PSinkInfo sinker = iSinkDao.querySinkerBySinkNo(seriousNum);
				assignMeter.setHeatSinkID(sinker.getId());
				//集中器ID
				assignMeter.setConcentratorID(concentrator.getId());
				//分配表型号
				assignMeter.setModel(meterEntity.getModel());
				//分配表软件版本号
				assignMeter.setSoftVersion(meterEntity.getSoftVersion());
				//分配表硬件版本号
				assignMeter.setHardVersion(meterEntity.getHardVersion());
				//分配表的安装位置
				assignMeter.setInstallPosition(meterEntity.getInstallPosition());
				//所属项目
				assignMeter.setProjectID(heatRoom.getProjectID());
				//所属小区
				assignMeter.setCommunityID(heatRoom.getCommunityID());
				//所属楼栋
				assignMeter.setBuildingID(heatRoom.getBuildingID());
				//所属热用户
				assignMeter.setRoomId(heatRoom.getId());
				this.iAssignMeterDao.saveOrUpdateEntity(assignMeter);
			}
		}
		return ResponseMsg.getInstance(true, "");
	}
	
	/**
	 * @return the iProjectDao
	 */
	public IProjectDao getiProjectDao() {
		return iProjectDao;
	}

	/**
	 * @param iProjectDao the iProjectDao to set
	 */
	public void setiProjectDao(IProjectDao iProjectDao) {
		this.iProjectDao = iProjectDao;
	}

	/**
	 * @return the iCommunityDao
	 */
	public ICommunityDao getiCommunityDao() {
		return iCommunityDao;
	}

	/**
	 * @param iCommunityDao the iCommunityDao to set
	 */
	public void setiCommunityDao(ICommunityDao iCommunityDao) {
		this.iCommunityDao = iCommunityDao;
	}

	/**
	 * @return the iBuildingDao
	 */
	public IBuildingDao getiBuildingDao() {
		return iBuildingDao;
	}

	/**
	 * @param iBuildingDao the iBuildingDao to set
	 */
	public void setiBuildingDao(IBuildingDao iBuildingDao) {
		this.iBuildingDao = iBuildingDao;
	}

	/**
	 * @return the iBuildingUnitDao
	 */
	public IBuildingUnitDao getiBuildingUnitDao() {
		return iBuildingUnitDao;
	}

	/**
	 * @param iBuildingUnitDao the iBuildingUnitDao to set
	 */
	public void setiBuildingUnitDao(IBuildingUnitDao iBuildingUnitDao) {
		this.iBuildingUnitDao = iBuildingUnitDao;
	}

	/**
	 * @return the iHeatRoomDao
	 */
	public IHeatRoomDao getiHeatRoomDao() {
		return iHeatRoomDao;
	}

	/**
	 * @param iHeatRoomDao the iHeatRoomDao to set
	 */
	public void setiHeatRoomDao(IHeatRoomDao iHeatRoomDao) {
		this.iHeatRoomDao = iHeatRoomDao;
	}

	/**
	 * @return the iConcentratorDao
	 */
	public IConcentratorDao getiConcentratorDao() {
		return iConcentratorDao;
	}

	/**
	 * @param iConcentratorDao the iConcentratorDao to set
	 */
	public void setiConcentratorDao(IConcentratorDao iConcentratorDao) {
		this.iConcentratorDao = iConcentratorDao;
	}

	/**
	 * @return the iAssignMeterDao
	 */
	public IAssignMeterDao getiAssignMeterDao() {
		return iAssignMeterDao;
	}

	/**
	 * @param iAssignMeterDao the iAssignMeterDao to set
	 */
	public void setiAssignMeterDao(IAssignMeterDao iAssignMeterDao) {
		this.iAssignMeterDao = iAssignMeterDao;
	}

	/**
	 * @return the iSinkDao
	 */
	public ISinkDao getiSinkDao() {
		return iSinkDao;
	}

	/**
	 * @param iSinkDao the iSinkDao to set
	 */
	public void setiSinkDao(ISinkDao iSinkDao) {
		this.iSinkDao = iSinkDao;
	}

	/**
	 * @return the iUserDao
	 */
	public IUserDao getiUserDao() {
		return iUserDao;
	}

	/**
	 * @param iUserDao the iUserDao to set
	 */
	public void setiUserDao(IUserDao iUserDao) {
		this.iUserDao = iUserDao;
	}

	/**
	 * @return the iRoleDao
	 */
	public IRoleDao getiRoleDao() {
		return iRoleDao;
	}

	/**
	 * @param iRoleDao the iRoleDao to set
	 */
	public void setiRoleDao(IRoleDao iRoleDao) {
		this.iRoleDao = iRoleDao;
	}

	/**
	 * @return the iUserRoleDao
	 */
	public IUserRoleDao getiUserRoleDao() {
		return iUserRoleDao;
	}

	/**
	 * @param iUserRoleDao the iUserRoleDao to set
	 */
	public void setiUserRoleDao(IUserRoleDao iUserRoleDao) {
		this.iUserRoleDao = iUserRoleDao;
	}

	/**
	 * @return the sysCommonUserRole
	 */
	public String getSysCommonUserRole() {
		return sysCommonUserRole;
	}

	/**
	 * @param sysCommonUserRole the sysCommonUserRole to set
	 */
	public void setSysCommonUserRole(String sysCommonUserRole) {
		this.sysCommonUserRole = sysCommonUserRole;
	}
	
}
